package com.mux.util.coder;

import static org.junit.Assert.assertArrayEquals;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * HMac   散列消息鉴别码  -- 单向 
 * @author devin.chen
 *
 */
public class HMACUtil {
	 public static final String KEY_MAC = "HmacMD5"; 
	 
	 
	   /** 
	     * BASE64加密 
	     *  
	     * @param key 
	     * @return 
	     * @throws Exception 
	     */  
	    public static String encryptBASE64(byte[] key) throws Exception {  
	        return (new BASE64Encoder()).encodeBuffer(key);  
	    }  
	  
	
    /** 
     * BASE64解密 
     *  
     * @param key 
     * @return 
     * @throws Exception 
     */  
    public static byte[] decryptBASE64(String key) throws Exception {  
        return (new BASE64Decoder()).decodeBuffer(key);  
    }  
  
    /** 
     * 初始化HMAC密钥 
     *  
     * @return 
     * @throws Exception 
     */  
    public static String initMacKey() throws Exception {  
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);  
  
        SecretKey secretKey = keyGenerator.generateKey();  
        return encryptBASE64(secretKey.getEncoded());  
    }  
  
	   /** 
     * HMAC加密 
     *  
     * @param data 
     * @param key 
     * @return 
     * @throws Exception 
     */  
    public static byte[] encryptHMAC(byte[] data, String key) throws Exception {  
  
        SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);  
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());  
        mac.init(secretKey);  
  
        return mac.doFinal(data);  
  
    }  
    
    public static void main(String[] args) throws Exception {
    	String key = initMacKey();
		System.err.println("Mac密钥:\n" + key);

		String inputStr = "简单加密";
		System.err.println("原文:\n" + inputStr);

		byte[] inputData = inputStr.getBytes();
		// 验证HMAC对于同一内容，同一密钥加密是否一致
		assertArrayEquals(Coder.encryptHMAC(inputData, key), Coder.encryptHMAC(
				inputData, key));
	}
}
